package com.baiye.www.spring.ioc.factory;


import com.baiye.www.spring.ioc.annotation.Autowired;
import com.baiye.www.spring.ioc.annotation.Service;
import com.baiye.www.spring.utils.ScanClassUtil;

import java.lang.reflect.Field;
import java.util.HashMap;
import java.util.Map;
import java.util.Properties;
import java.util.Set;

/**
 * Created with IntelliJ IDEA.
 *
 * @Author: baiye
 * @Date: 2021/08/07/10:36
 * @Description:
 */
public class AnnotatedBeanFactory implements BeanFactory {

    public Properties props = new Properties();
    /**
     * ioc容器
     */
    public Map<String, Object> beans = new HashMap<>();
    /**
     * 类名和全限定类名
     */
    public Map<String, String> nameToPath = new HashMap<>();


//    static {
//        try {
//            props = new Properties();
//            //获取properties文件的流对象
//            InputStream in = BeanFactory.class.getClassLoader().getResourceAsStream("bean.properties");
//            props.load(in);
//            beans = new HashMap<String,Object>();
//            //取出配置文件中所有的Key
//            Set<String> keys = props.stringPropertyNames();
//            //遍历枚举
//            for (String key : keys) {
//                 String beanName = (String) props.get(key);
//                Object value = Class.forName(beanName).newInstance();
//                //把key和value存入容器中
//                beans.put(key,value);
//            }
//            DoAutoWired();
//        }catch(Exception e){
//            throw new ExceptionInInitializerError("初始化properties失败！");
//        }
//    }

    public static void main(String[] args) {

//        Set<Class<?>> clazz = ScanClassUtil.getClasses("com.baiye.www");
//        System.out.println("ok");
    }

    /**
     * 初始化扫描注入
     */
    public void init(String path) throws IllegalAccessException, InstantiationException {

        Set<Class<?>> clazz = ScanClassUtil.getClasses(path);
        for (Class c : clazz) {
            Object o = null;
            if (!c.isAnnotation()) {
                if (c.isInterface()) {
                    for (Class cc : clazz) {
                        if (cc.isAnnotationPresent(Service.class)) {
                            if (cc.getInterfaces()[0].equals(c)) {
                                o = cc.newInstance();
                                break;
                            }
                        }
                    }
                } else {
                    o = c.newInstance();
                }


                String classPath = c.getName();
                beans.put(classPath, o);
                String[] temp = classPath.split("\\.");
                String name = temp[temp.length - 1];
                nameToPath.put(name, classPath);
            }

        }

        DoAutoWired();
        System.out.println("注入完成");

    }

    @Override
    public Object getBean(String beanName) {
        return beans.get(nameToPath.get(beanName));
    }

    private void DoAutoWired() throws IllegalAccessException {
        if (beans == null) {
            return;
        }
        for (Map.Entry<String, Object> bean : beans.entrySet()) {
            Field[] fields = bean.getValue().getClass().getDeclaredFields();
            for (Field field : fields) {
                if (field.isAnnotationPresent(Autowired.class)) {
                    Autowired autowired = field.getAnnotation(Autowired.class);
                    String beanName = autowired.value().trim();
                    //没写则为类型名
                    if ("".equals(beanName)) {
                        beanName = field.getType().getName();
                    }
                    field.setAccessible(true);
                    field.set(bean.getValue(), beans.get(beanName));
                }
            }
        }
    }
}
